﻿using CodeToHtml;
using Microsoft.VisualStudio.TestTools.UnitTesting;

namespace CodeToHtml {
    [TestClass]
    public class CodeReaderTest {
        readonly CodeReaderParameters _codeReaderParameters = CodeReaderParameters.CreateCSharpParameters();

        [TestMethod]
        public void TestReadString() {
            const string code = "\"Hello World\"";
            CodeReader reader = new CodeReader(code, _codeReaderParameters);
            CodeItem codeItem = reader.ReadCodeItem();
            Assert.AreEqual(code, codeItem.String);
            Assert.AreEqual(CodeItemType.String, codeItem.Type);
            Assert.AreEqual(true, reader.IsEndOfString());
        }

        [TestMethod]
        public void TestReadStringWithEscapes() {
            const string code = "\"Hello \\\"World\"";
            CodeReader reader = new CodeReader(code, _codeReaderParameters);
            CodeItem codeItem = reader.ReadCodeItem();
            Assert.AreEqual(code, codeItem.String);
            Assert.AreEqual(CodeItemType.String, codeItem.Type);
            Assert.AreEqual(true, reader.IsEndOfString());
        }

        [TestMethod]
        public void TestReadCharacter() {
            const string code = "'a'";
            CodeReader reader = new CodeReader(code, _codeReaderParameters);
            CodeItem codeItem = reader.ReadCodeItem();
            Assert.AreEqual(code, codeItem.String);
            Assert.AreEqual(CodeItemType.String, codeItem.Type);
            Assert.AreEqual(true, reader.IsEndOfString());
        }

        [TestMethod]
        public void TestReadCharacterWithEscapes() {
            const string code = "'\\''";
            CodeReader reader = new CodeReader(code, _codeReaderParameters);
            CodeItem codeItem = reader.ReadCodeItem();
            Assert.AreEqual(code, codeItem.String);
            Assert.AreEqual(CodeItemType.String, codeItem.Type);
            Assert.AreEqual(true, reader.IsEndOfString());
        }

        [TestMethod]
        public void TestReadLineComment() {
            const string code = "// This is a line comment\n";
            CodeReader reader = new CodeReader(code, _codeReaderParameters);
            CodeItem codeItem = reader.ReadCodeItem();
            Assert.AreEqual(code, codeItem.String);
            Assert.AreEqual(CodeItemType.Comment, codeItem.Type);
            Assert.AreEqual(true, reader.IsEndOfString());
        }

        [TestMethod]
        public void TestReadBlockComment() {
            const string code = "/* This is a\nblock comment */";
            CodeReader reader = new CodeReader(code, _codeReaderParameters);
            CodeItem codeItem = reader.ReadCodeItem();
            Assert.AreEqual(code, codeItem.String);
            Assert.AreEqual(CodeItemType.Comment, codeItem.Type);
            Assert.AreEqual(true, reader.IsEndOfString());
        }

        [TestMethod]
        public void TestReadKeywordEndOfString() {
            const string code = "this";
            CodeReader reader = new CodeReader(code, _codeReaderParameters);
            CodeItem codeItem = reader.ReadCodeItem();
            Assert.AreEqual(code, codeItem.String);
            Assert.AreEqual(CodeItemType.Keyword, codeItem.Type);
            Assert.AreEqual(true, reader.IsEndOfString());
        }

        [TestMethod]
        public void TestReadKeyword() {
            const string code = "this ";
            CodeReader reader = new CodeReader(code, _codeReaderParameters);
            CodeItem codeItem = reader.ReadCodeItem();
            Assert.AreEqual("this", codeItem.String);
            Assert.AreEqual(CodeItemType.Keyword, codeItem.Type);
            Assert.AreEqual(false, reader.IsEndOfString());
        }

        [TestMethod]
        public void TestReadOtherWithKeywordInName() {
            const string code = "mythis";
            CodeReader reader = new CodeReader(code, _codeReaderParameters);
            CodeItem codeItem = reader.ReadCodeItem();
            Assert.AreEqual(code, codeItem.String);
            Assert.AreEqual(CodeItemType.Other, codeItem.Type);
            Assert.AreEqual(true, reader.IsEndOfString());
        }

        [TestMethod]
        public void TestReadDelimiter() {
            const string code = ".";
            CodeReader reader = new CodeReader(code, _codeReaderParameters);
            CodeItem codeItem = reader.ReadCodeItem();
            Assert.AreEqual(code, codeItem.String);
            Assert.AreEqual(CodeItemType.Delimiter, codeItem.Type);
            Assert.AreEqual(true, reader.IsEndOfString());
        }
    }
}
